home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1997 February
/
EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso
/
enigma
/
earcd
/
utility
/
utilwb
/
closewbpatch.lzh
/
CloseWBPatch
/
CloseWbPatch.s
next >
Wrap
Text File
|
1996-10-29
|
18KB
|
479 lines
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* *
* * * * * *
* * * *
* * * _________________________________________ *
* * * / / *
* * * / Assembly Source of / *
* * * / CloseWbPatch v1.1 / *
* * * * * * * / / *
* * * * * / - BURNAND Patrick - / *
* * * * * / / *
* * * * ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ *
* * * *
* * * * * * *
* *
* *
* *
* This source code is distributed with the CloseWbPatch package and *
* may not be distrbuted by another way. It must always be kept in *
* original and unmodifed form. This file is distributed for lear- *
* ning purposes and as example only. You are allowed to print this *
* file but you aren't allowed to distribute it in printed form. If *
* you want to make others uses of this source code, contact the *
* author. My adress can be found in the doc file of this program. *
* *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
** Main
** 1.0
** CONSTANTES GLOBALES **
ExecBase EQU 4
** PROCÉDURES INTERNES **
* XREF NewFunction Code de la nouvelle fonction CloseWorkbench()
** PROCÉDURES EXTERNES **
AddPort EQU -$0162
AllocMem EQU -$00c6
AllocSignal EQU -$014a Exec.AllocSignal (SignalNum) (d0)
ClearCacheU EQU -$027c Exec.ClearCacheU () ()
CloseLibrary EQU -$019E Exec.CloseLibrary (library) (a1)
CopyMem EQU -$0270
CreateMsgPort EQU -$029a
DeleteMsgPort EQU -$02a0
FindPort EQU -$0186
FindTask EQU -$0126 Exec.FindTask (name) (a1)
Forbid EQU -$0084
FreeMem EQU -$00d2
FreeSignal EQU -$0150 Exec.FreeSignal (SignalNum) (d0)
GetMsg EQU -$0174
OpenLibrary EQU -$0228 Exec.OpenLibrary (name, version) (a1, d0)
Permit EQU -$008a
PutMsg EQU -$016e
RemPort EQU -$0168
ReplyMsg EQU -$017a Exec.ReplyMsg (message) (a1)
SetFunction EQU -$01a4
SetTaskPri EQU -$012c
WaitPort EQU -$0180
** CODE **
Main:
Movem.l a3/a6,-(a7)
Move.l ExecBase,a6 OwnTask := FindTask (NIL); OwnTask := pointeur sur la tâche courante
Suba.l a1,a1
Jsr FindTask(a6)
Move.l d0,OwnTask
Move.l d0,a3
* Move.l OwnTask,a3 IF (Process.pr_CLI # NIL) THEN SI (le programme n'est pas lancé depuis le CLI)
Tst.l $ac(a3)
Bne.w M_NoWorkbench
* REPEAT REPETER
M_WaitWbMsg:
* Move.l ExecBase,a6 ! := WaitPort (OwnTask.pr_MsgPort); Attendre sur le port de la tâche
* Move.l OwnTask,a3
Lea $5c(a3),a0
Jsr WaitPort(a6)
* Move.l ExecBase,a6 WbMsg := GetMsg (OwnTask.pr_MsgPort); WbMsg := message du workbench
* Move.l OwnTask,a3
Lea $5c(a3),a0
Jsr GetMsg(a6)
Move.l d0,WbMsg
* Tst.l d0
* Tst.l WbMsg UNTIL (WbMsg # NIL); JUSQU'À CE QUE (WbMsg soit valide)
Beq.s M_WaitWbMsg
Move.l ExecBase,a6 ReplyMsg (WbMsg); Rendre le message au workbench
Move.l WbMsg(pc),a1
Jsr ReplyMsg(a6)
Moveq #0,d0 ABORT;
Movem.l (a7)+,a3/a6
Rts
M_NoWorkbench:
* END; FIN
* Move.l ExecBase,a6 Forbid (); Interdire la commutation des tâches
Jsr Forbid(a6)
* Move.l ExecBase,a6 OldPort := FindPort (PortNamePtr); Voir si le patch est déjà installé
Lea PortNamePtr(pc),a1
Jsr FindPort(a6)
Move.l d0,OldPort
* Move.l ExecBase,a6 Permit (); Autoriser la commutation des tâches
Jsr Permit(a6)
Tst.l OldPort IF (OldPort=NIL) THEN SI (le patch n'est pas encore installé)
Bne.w M_NoMsgPort
* Move.l ExecBase,a6 SigBit := AllocSignal (-1);
Moveq #-1,d0
Jsr AllocSignal(a6)
Move.b d0,SigBit
Cmp.b #$FF,d0
* Cmp.b #$FF,SigBit IF NOT (SigBit=-1) THEN Allouer un signal
Beq.w M_NoSignal SI (l'allocation du signal a fonctionné)
Lea MsgPort(pc),a0 Installer le port de message
Move.b SigBit(pc),15(a0) MsgPort.mp_SigBit := SigBit; Bit de signal
Move.l OwnTask(pc),16(a0) MsgPort.mp_SigTask := OwnTask; Signaler notre propre tâche
* Move.l ExecBase,a6 AddPort (MsgPort); Rendre le port public (visible des autres tâches)
Lea MsgPort(pc),a1
Jsr AddPort(a6)
* Move.l ExecBase,a6 IntuitionBase := OpenLibrary (ADR(IntuitionName),36); Ouvrir la librairie Intuition
Lea IntuitionName(pc),a1
Moveq #36,d0
Jsr OpenLibrary(a6)
Move.l d0,IntuitionBase
Tst.l d0
* Tst.l IntuitionBase IF (IntuitionBase#NIL) THEN SI (l'ouverture de la librairie a fonctionné)
Beq.w M_NoIntuition
* Move.l ExecBase,a6 OldFunction := SetFunction (IntuitionBase, -$004e, ADR(NewFunction)); Installer la nouvelle fonction
Move.l d0,a1
* Move.l IntuitionBase,a1
Suba.l a0,a0
Move.w #-$004e,a0
Move.l #NewFunction,d0
Jsr SetFunction(a6)
Move.l d0,OldFunction
* DO FAIRE
Forever:
* Move.l ExecBase,a6 ! := WaitPort (MsgPort); Attendre un message de l'éventuelle autre tâche
Lea MsgPort(pc),a0
Jsr WaitPort(a6)
* Move.l ExecBase,a6 ! := GetMsg (MsgPort); Prendre le message
Lea MsgPort(pc),a0
Jsr GetMsg(a6)
Eor.b #$FF,Active Active := NOT (Active); Inverser l'état d'activation du patch
Lea M_EasyStruct(pc),a1
Move.l #ActiveText,12(a1) M_EasyStruct.Text := ActiveText Texte de la requête := ActiveText
Move.l #OkGadgets,16(a1) M_EasyStruct.Gadgets := OkGadgets Gadgets de la requête := OkGadgets
Tst.b Active IF (Active=FALSE) THEN SI (le patch n'est pas actif)
Bne.s M_Inactive
Move.l #InactiveText,12(a1) M_EasyStruct.Text := InactiveText Texte de la requête := InactiveText
M_Inactive:
* END; FIN
Movem.l a2/a3/a6,-(a7)
Move.l IntuitionBase(pc),a6
Suba.l a2,a2 (IDCMP_Ptr)
* Suba.l a3,a3 (ArgList)
Move.l a2,a3
* Suba.l a0,a0 (Window)
Move.l a3,a0
Jsr EasyRequestArgs(a6) ! := EasyRequestArgs(NIL, M_EasyStruct, NIL, NIL) Afficher la requête
Movem.l (a7)+,a2/a3/a6
Bra.s Forever LOOP INDÉFINIMENT
* Move.l ExecBase,a6 CloseLibrary (IntuitionBase); Fermer la librairie Intuition
Move.l IntuitionBase(pc),a1
Jsr CloseLibrary(a6)
M_NoIntuition:
* END; FIN
* Move.l ExecBase,a6 Forbid (); Interdire la commutation des tâches
Jsr Forbid(a6)
* Move.l ExecBase,a6 RemPort (MsgPort); Rendre le port de message privé (Invisible des autres tâches)
Lea MsgPort(pc),a1
Jsr RemPort(a6)
* Move.l ExecBase,a6 Permit (); Autoriser la commutation des tâches
Jsr Permit(a6)
* Move.l ExecBase,a6 FreeSignal (SigBit); Libérer le bit de signal
Moveq #0,d0
Move.b SigBit(pc),d0
Jsr FreeSignal(a6)
M_NoSignal:
* END; FIN
Bra.s M_NoMsgPortF
M_NoMsgPort:
* ELSE SINON
* Move.l ExecBase,a6 PutMsg (OldPort, Message); Envoyer un message à l'autre tâche
Move.l OldPort(pc),a0
Lea Message(pc),a1
Jsr PutMsg(a6)
M_NoMsgPortF:
* END; FIN
Moveq #0,d0 RETURN M_Return; Retourner le code d'erreur
Movem.l (a7)+,a3/a6
Rts
** CONSTANTES GLOBALES **
Version dc.b '$VER: CloseWbPatch 1.1 (14.10.96)',0
CloseWbTitle dc.b 'CloseWbPatch 1.1 by Burnand Patrick',0
** CONSTANTES LOCALES **
IntuitionName dc.b 'intuition.library',0
PortNamePtr dc.b 'CloseWbPatch',0
Message dc.l 0 Message.mn_Node.ln_Succ
dc.l 0 Message.mn_Node.ln_Pred
dc.b 0 Message.mn_Node.ln_Type
dc.b 0 Message.mn_Node.ln_Pri
dc.l PortNamePtr Message.mn_Node.ln_Name
dc.l 0 Message.mn_ReplyPort
dc.w 24 Message.mn_Length
dc.l -1 Contenu du message
ActiveText dc.b 'CloseWbPatch is now active !',0
InactiveText dc.b 'CloseWbPatch is now inactive !',0
OkGadgets dc.b 'Ok !',0
** VARIABLES GLOBALES **
OldFunction dc.l 0 APTR Pointeur sur la fonction originale
Active dc.b $FF BOOLEAN Initialisé à FALSE
** VARIABLES LOCALES **
MsgPort dc.l 0 MsgPort.mp_Node.ln_Succ
dc.l 0 MsgPort.mp_Node.ln_Pred
dc.b 4 MsgPort.mp_Node.ln_Type = NT_MSGPORT
dc.b 0 MsgPort.mp_Node.ln_Pri = 0
dc.l PortNamePtr MsgPort.mp_Node.ln_Name = PortNamePtr
dc.b 0 MsgPort.mp_Flags = PA_SIGNAL
dc.b 0 MsgPort.mp_SigBit
dc.l 0 MsgPort.mp_SigTask
dc.l 0 MsgPort.mp_MsgList
dc.l 0 ...
dc.l 0 ...
dc.w 0 ...
M_EasyStruct dc.l 20 sizeof(EasyStruct)
dc.l 0 Flags
dc.l CloseWbTitle Title
dc.l 0 TextFormat
dc.l 0 GadgetFormat
OwnTask dc.l 0 APTR Exec.TaskPtr
ActualPri dc.b 0 BYTE
SigBit dc.b 0 BYTE Exec.SignalBit
dc.b 0
OldPort dc.l 0 APTR Exec.MsgPortPtr
IntuitionBase dc.l 0 APTR Intuition.LibraryBasePtr
WbMsg dc.l 0 APTR Exec.MessagePtr
** NewFunction (): BOOLEAN
** 1.1
** PARAMETRES **
* Entree:
* Sortie:
* BOOLEAN TRUE si le workbench a été fermé. FALSE sinon.
** CONSTANTES GLOBALES **
TaskNameMaxLen EQU 30
** PROCÉDURES EXTERNES **
WBenchToFront EQU -$0156 Intuition.WBenchToFront () ()
WBenchToBack EQU -$0150 Intuition.WBenchToBack () ()
EasyRequestArgs EQU -$024c
** CODE **
XDEF NewFunction
NewFunction:
Tst.b Active IF (Active=TRUE) THEN SI (le patch est actif)
Beq.w NF_Inactive
Jsr WBenchToFront(a6) IF (WBenchToFront()=TRUE) THEN Mettre l'écran du Workbench en avant-plan
Tst.b d0 SI (l'écran du workbench existe)
Beq.w NF_NoWorkbench
Move.l a6,-(a7)
Move.l ExecBase,a6 ! := FindTask (NIL); ! := pointeur sur la tâche courante
Suba.l a1,a1
Jsr FindTask(a6)
Move.l (a7)+,a6
Lea CloseWbText0(pc),a0 Générer chaîne à afficher
Lea CloseWbText(pc),a1
NF_CpLoop1:
Move.b (a0)+,(a1)+
Bne.s NF_CpLoop1
Subq.w #1,a1
Move.l d0,a0 Ajouter le nom de la tâche
Move.l 10(a0),a0 Copier # chars maxi
Move.b #TaskNameMaxLen,d0
NF_CpLoop2:
Subq.b #1,d0
Beq.s NF_CpLoop2_O
Move.b (a0)+,(a1)+
Bne.s NF_CpLoop2
Subq.w #1,a1
NF_CpLoop2_O:
Lea CloseWbText1(pc),a0 Ajouter fin du txt
NF_CpLoop3:
Move.b (a0)+,(a1)+
Bne.s NF_CpLoop3
Movem.l a2/a3,-(a7)
Lea NF_EasyStruct(pc),a1 (EasyStruct)
Move.l #CloseWbText,12(a1) NF_EasyStruct.Text := CloseWbText1 Texte de la requête := CloseWbText1
Move.l #CloseWbGadgets1,16(a1) NF_EasyStruct.Gadgets := CloseWbGadgets1 Gadgets de la requête := CloseWbGadgets1
Suba.l a2,a2 (IDCMP_Ptr)
* Suba.l a3,a3 (ArgList)
Move.l a2,a3
* Suba.l a0,a0 (Window)
Move.l a3,a0
Jsr EasyRequestArgs(a6) IF (EasyRequestArgs(NIL, NF_EasyStruct, NIL, NIL) = 0) THEN Afficher la requête
Movem.l (a7)+,a2/a3 SI (l'utilisateur sélectionne non)
Tst.b d0
Bne.s NF_Yes
Move.b #0,NF_Return NF_Return := FALSE; Le code de retour est faux (écran n'a pas pu être fermé)
Bra.s NF_No ELSE SINON
NF_Yes:
NF_Loop:
* REPEAT REPETER
Move.l OldFunction(pc),a0 Flag := OldFunction(); Essayer de fermer l'écran (en appelant fonction originale)
Jsr (a0) Le Flag égale ce que retourne la fonction originale
Move.b d0,Flag
* Move.b Flag,NF_Return NF_Return := Flag; Le code de retour égale le Flag
Move.b d0,NF_Return
* Tst.b Flag IF (Flag=FALSE) THEN SI (le Flag=FALSE)
Tst.b d0
Bne.s NF_FlagOk
Movem.l a2/a3,-(a7)
Lea NF_EasyStruct(pc),a1 (EasyStruct)
Move.l #CloseWbText2,12(a1) NF_EasyStruct.Text := CloseWbText2 Texte de la requête := CloseWbText2
Move.l #CloseWbGadgets2,16(a1) NF_EasyStruct.Gadgets := CloseWbGadgets2 Gadgets de la requête := CloseWbGadgets2
Suba.l a2,a2 (IDCMP_Ptr)
* Suba.l a3,a3 (ArgList)
Move.l a2,a3
* Suba.l a0,a0 (Window)
Move.l a3,a0
Jsr EasyRequestArgs(a6) IF (EasyRequestArgs(NIL, NF_EasyStruct, NIL, NIL)=0) THEN Afficher la requête
Movem.l (a7)+,a2/a3 SI (la requête retourne faux)
Tst.b d0
Bne.s NF_Retry
Eor.b #$FF,Flag Flag := TRUE; Le Flag égale TRUE
* END; FIN
NF_Retry:
* END; FIN
NF_FlagOk:
Tst.b Flag UNTIL (Flag=TRUE); JUSQU'À CE QUE (le Flag=TRUE)
Beq.s NF_Loop
NF_No:
* END; FIN
Bra.s NF_NoWorkbenchF ELSE SINON
NF_NoWorkbench:
Move.b #0,NF_Return NF_Return := FALSE; Le code de retour est faux (écran non-présent)
NF_NoWorkbenchF:
* END; FIN
Bra.s NF_InactiveF
NF_Inactive:
* ELSE SINON
Move.l OldFunction(pc),a0 NF_Return := OldFunction(); Essayer de fermer l'écran (en appelant fonction originale)
Jsr (a0) Le code de retour égale ce que retourne la fonction originale
Move.b d0,NF_Return
NF_InactiveF:
* END; FIN
Moveq #0,d0 RETURN NF_Return; Retourner le code de retour
Move.b NF_Return(pc),d0
Rts
** VARIABLES GLOBALES **
* XREF OldFunction
* XREF Active
** CONSTANTES LOCALES **
CloseWbText0 dc.b 'The task named "',0
CloseWbText0F
CloseWbText1 dc.b '" wants',10
dc.b "to close the Workbench screen...",0
CloseWbText1F
CloseWbGadgets1 dc.b "Allow closing|Don't close",0
CloseWbText2 dc.b "Unable to close the Workbench screen.",10
dc.b "Close all the non-Workbench windows.",0
CloseWbGadgets2 dc.b 'Retry|Cancel',0
** VARIABLES LOCALES **
Flag dc.b 0 BOOLEAN Initialisé à FALSE
NF_Return dc.b 0 BOOLEAN Initialisé à FALSE
NF_EasyStruct dc.l 20 sizeof(EasyStruct)
dc.l 0 Flags
dc.l CloseWbTitle Title
dc.l 0 TextFormat
dc.l 0 GadgetFormat
CloseWbText: ds.b (CloseWbText0F-CloseWbText0)+(CloseWbText1F-CloseWbText1)+TaskNameMaxLen+2
* Buffer pour chaîne à afficher
End